<?php
/**
 * RDFIOEquivalentURIHandler contains functionality for converting RDF URIs to
 * appropriate wiki titles, and vice versa. The conversion can be done
 * differently depending on configuration, and RDFIOEquivalentURIHandler stores
 * the configuration it is using, in internal variables.
 */
class RDFIOEquivalentURIHandler {

    protected $m_wikititlepropertyuris;
    protected $m_nsprefixes;
    protected $m_tripleindex;
    protected $m_usensprefixes;
    protected $m_store;

    function __construct( $advwikititleuris = '' ) {
        global $rdfiogPropertiesToUseAsWikiTitle, $rdfiogUsePseudoNamespaces;

        if ( !empty( $rdfiogUsePseudoNamespaces ) ) {
            // use parameter set in LocalSettings.php
            $this->m_usensprefixes = $rdfiogUsePseudoNamespaces;
        } else {
            $this->m_usensprefixes = false;
        }

        if ( !empty( $rdfiogPropertiesToUseAsWikiTitle ) ) {
            $this->m_wikititlepropertyuris = $rdfiogPropertiesToUseAsWikiTitle;
        } else {
            $this->m_wikititlepropertyuris = array(
            	'http://semantic-mediawiki.org/swivt/1.0#page', // Suggestion for new property
            	'http://www.w3.org/2000/01/rdf-schema#label',
            	'http://purl.org/dc/elements/1.1/title',
            	'http://www.w3.org/2004/02/skos/core#preferredLabel',
            	'http://xmlns.com/foaf/0.1/name'
            	);
        }

        $this->m_store = new RDFIOStore();
    }

    /**
     * Takes an ARC2 ns prefix mapping array and stores in class variable
     * @param array $nsprefixmapping
     */
    public function setNSPrefixes( $nsprefixmapping ) {
        $this->m_nsprefixes = $nsprefixmapping;
    }

    /**
     * Takes an ARC2 triple index and stores in class variable
     * @param array $tripleindex
     */
    public function setTripleIndex( $tripleindex ) {
        $this->m_tripleindex = $tripleindex;
    }

    /**
     * Converts a (full) URI into a string suitable for use as wiki title
     * @param string $uri
     * @return string $wikititle
     */
    public function getWikiTitleForURI( $uri ) {
        global $rdfiogUsePseudoNamespaces;

        // URI resolver URIs should never be used as original URI, and therefore is not
        // checked for. 
        if ( !RDFIOUtils::isURIResolverURI( $uri ) ) {
            $titleByStoredOriginalUri = $this->getWikiTitleByStoredOriginalUri( $uri );
        }

        if ( $titleByStoredOriginalUri != '' ) {
            $wikititle = $titleByStoredOriginalUri;
        } else {
            $titlebypropertyuriindex = $this->getWikiTitleByPropertyURIIndex( $uri );
            if ( $titlebypropertyuriindex != '' ) {
                $wikititle = $titlebypropertyuriindex;
            } else if ( $rdfiogUsePseudoNamespaces ){
                $wikititle = $this->abbreviateNSFromURI( $uri );
            } else {
                $wikititle = RDFIOUtils::extractLabelFromURI( $uri );
            }
            $wikititle = RDFIOUtils::sanitizeWikiTitle( $wikititle );
        }
        if ( !RDFIOUtils::isURL( $wikititle ) ) {
            $wikititle = ucfirst( $wikititle );
        }
        return $wikititle;
    }

    /**
     * Check the wiki for an article with the $origuri set as "Original URI" through
     * the "Original URI" property, and return the title of that article.
     * @param string $origuri
     * @return string $wikititle
     */
    public function getWikiTitleByStoredOriginalUri( $origuri ) {
        $wikititle = $this->m_store->getWikiTitleByOriginalURI( $origuri );
        return $wikititle;
    }

    /**
     * Convert a namespace into its corresponding prefix, using prefix definitions
     * submitted in imported RDF/XML, if available.
     * @param string $ns
     * @return string $prefix
     */
    function getPrefixForNS( $ns ) {
        // Namespace prefis definitions are stored in the 'nsp' array
        // of the (RDF/XML) parser object, since import.
        $prefix = $this->m_nsprefixes[$ns];
        if ( $prefix == '' ) $prefix = $ns;
        return $prefix;
    }

    /**
     * Use a "natural language" property, such as dc:title or similar, as wiki title
     * @param string $subject
     * @return string $title
     */
    function getWikiTitleByPropertyURIIndex( $subject ) {
        // Looks through, in order, the uri:s in $this->m_wikititlepropertyuris
        // to see if any of them is set for $subject. if so, return corresponding
        // value as title.
        foreach ( $this->m_wikititlepropertyuris as $advtitleuri ) {
            $titleuri = $this->m_tripleindex[$subject][$advtitleuri][0]['value'];
            $title = $this->abbreviateNSFromURI( $titleuri );
            if ( $title != '' ) {
                break;
            }
        }
        return $title;
    }

    /**
     * Abbreviate the base URI into a "pseudo-wiki-title-namespace"
     * @param string $uri
     * @return string $uri
     */
    public function abbreviateNSFromURI( $uri ) {
        $uriParts = RDFIOUtils::splitURI( $uri );
        if ( $uriParts[1] == '' ) {
            $uri = $uriParts[0];
        } else if ( substr($uriParts[0], 0, 1) == '_' ) {
            // Change ARC:s default "random string", to indicate more clearly that
            // it lacks title
            $uri = str_replace('arc','untitled',$uriParts[1]);
        } else if ( substr($uriParts[0], -1) == ':' ) {
            // Don't add another colon
            $uri = $this->getPrefixForNS($uriParts[0]) . $uriParts[1];
        } else {
            $nsprefix = $this->getPrefixForNS($uriParts[0]);
            if ( !$this->m_usensprefixes || substr($nsprefix, 0, 4) == 'http' ) {
                $uri = $uriParts[1];
            } else {
                $uri = $this->getPrefixForNS($uriParts[0]) . ':' . $uriParts[1];
            }
        }
        return $uri;
    }
    
}